<?php

namespace app\api\model;

use app\api\controller\Wxpay;
use Exception;
use think\Cache;
use think\Db;
use traits\model\SoftDelete;

class RecycleOrderModel extends BaseModel
{
    use SoftDelete;

    protected $pk = 'id';
    protected $table = 'hs_recycle_order';
    protected static $tableName = 'recycle_order';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    //状态常量
    const STATUS_PENDING_ORDER = 1;//待接单
    const STATUS_ORDER_RECEIVED = 2;//已接单
    const STATUS_COMPLETED = 3;//已完成
    const STATUS_CANCEL = 4;//已取消

    //支付类型常量
    const PAY_TYPE_OFFLINE = 1;//线下支付
    const PAY_TYPE_PLATFORM = 2;//线上平台

    public static function status()
    {
        return [
            self::STATUS_PENDING_ORDER => '待接单',
            self::STATUS_ORDER_RECEIVED => '已接单',
            self::STATUS_COMPLETED => '已完成',
            self::STATUS_CANCEL => '已取消',
        ];
    }

    public function getImagesAttr($value)
    {
        if ($value) {
            $host = $_SERVER['HTTP_HOST'];
            $images = explode(',', $value);
            foreach ($images as $k => $v) {
                $images[$k] = 'https://' . $host . $v;
            }
            return $images;
        }
        return '';
    }

    public static function getOrder($id)
    {
        return self::where('id', $id)->find();
    }

    public function item()
    {
        return $this->hasMany(RecycleOrderItemModel::class, 'order_id', 'id');
    }

    public static function check($id, $status)
    {
        $statusInfo = self::status();
        $model = self::where('id', $id)->find();
        if (!$model) {
            return array('code' => -1, 'msg' => '订单不存在');
        }
        if ($model->status != $status) {
            return array('code' => -1, 'msg' => "不是{$statusInfo[$status]}订单,操作失败");
        }
        return array('code' => 1, 'data' => $model);
    }

    public static function cancelCheck($no)
    {
        $model = self::where('no', $no)->find();
        if (!$model) {
            return array('code' => -1, 'msg' => '订单不存在');
        }
        if ($model->status == self::STATUS_COMPLETED) {
            return array('code' => -1, 'msg' => "订单已完成，无法取消");
        }
        if ($model->status == self::STATUS_CANCEL) {
            return array('code' => -1, 'msg' => "订单已是取消状态，无需再次取消");
        }
        return array('code' => 1, 'data' => $model);
    }

    public static function createOrder($data = [])
    {
        try {
            if (isset($data['images']) && is_array($data['images'])) {
                $images = $data['images'];
                foreach ($images as $k => $v) {
                    $pregInfo = preg_match('/^(data:\s*image\/(\w+);base64,)/', $v, $photoInfo);
                    if (!in_array($photoInfo[2], array('jpg', 'png', 'bmp'))) {
                        throw new Exception('图像格式错误');
                    }
                    if (!$pregInfo) {
                        throw new Exception('图像格式错误');
                    }
                    $clearBase64HeadWithPhoto = str_replace($photoInfo[1], '', $v);
                    $clearBase64HeadWithPhoto = str_replace(' ', '+', $clearBase64HeadWithPhoto);
                    $imagePath = BaseModel::saveImg($clearBase64HeadWithPhoto, $photoInfo[2]);
                    if (!$imagePath) {
                        throw new Exception('上传失败');
                    }
                    $path[] = $imagePath;
                }
                $path = implode(',', $path);
                $data['images'] = $path;
            }
            Db::startTrans();
            $service_fee = ConfigModel::getValue('recovery_service_fee', 'basic');
            $order_info = [
                'no' => self::getNewOrderId(1),
                'user_id' => $data['user_id'],
                'reserve_time' => strtotime($data['reserve_time']),
                'province' => $data['province'],
                'city' => $data['city'],
                'district' => $data['district'],
                'address' => $data['address'],
                'real_name' => $data['real_name'],
                'mobile' => $data['mobile'],
                'estimate_weight' => $data['estimate_weight'],
                'estimate_price' => $data['estimate_price'],
                'service_fee' => $service_fee,
                'remark' => isset($data['remark']) ? $data['remark'] : '',
                'longitude' => isset($data['longitude']) ? $data['longitude'] : '',
                'latitude' => isset($data['latitude']) ? $data['latitude'] : '',
                'images' => isset($data['images']) ? $data['images'] : '',
            ];
            $order = self::create($order_info);
            if (!$order) {
                throw new Exception('订单生成失败!');
            }
            $itemData = [];
            $category = CategoryModel::typeArr(CategoryModel::TYPE_RECYCLE);
            $priceArr = RecyclePriceModel::priceArr();
            foreach ($data['category'] as $k => $v) {
                $category_name = isset($category[$v['id']]) ? $category[$v['id']] : '';
                $price = isset($priceArr[$v['id']]) ? $priceArr[$v['id']] : 0;
                $itemData[] = [
                    'order_id' => $order->id,
                    'category_id' => $v['id'],
                    'category_name' => $category_name,
                    'weight' => $v['weight'],
                    'price' => $price,
                    'sum_price' => bcmul($v['weight'], $price, 2),
                    'createtime' => time(),
                ];
            }
            if (!RecycleOrderItemModel::insertAll($itemData)) {
                throw new Exception('订单规格生成失败!');
            }
            //获取自动接单的设置距离
            $configDistance = ConfigModel::getValue('distance', 'basic');
            $rider_id = 0;//骑手id
            //获取用户下单省市下的所有回收员
            $riders = RiderModel::where('province', $data['province'])->where('city', $data['city'])->where('status', RiderModel::STATUS_SUCCESS)->select();
            if ($riders) {
                shuffle($riders);
                foreach ($riders as $rider) {
                    $km = BaseModel::distance($rider['longitude'], $rider['latitude'], $data['longitude'], $data['latitude']);
                    if ($km <= $configDistance) {
                        $rider_id = $rider->user_id;
                        break;
                    }
                }
            }
            if ($rider_id) { //如果有可以接单的骑手，订单自动分配给骑手
                $order->role_id = $rider_id;
                $order->status = RecycleOrderModel::STATUS_ORDER_RECEIVED;
                $order->take_time = time();
                $order->save();
            }
            Db::commit();
            return $order;
        } catch (Exception $e) {
            Db::rollback();
            return self::setErrorInfo($e->getMessage());
        }
    }

    /**
     * 生成订单唯一id
     * @return string
     */
    public static function getNewOrderId($type)
    {
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        $no = $type . $msectime . mt_rand(10000, 99999);
        if (self::where('no', $no)->find()) {
            $no = $type . $msectime . mt_rand(10000, 99999);
        }
        return $no;
    }

    //接单
    public static function take($uid, $order)
    {
        try {
            $key = md5($order->no);
            if (Cache::has($key)) {
                throw new Exception('订单已被接走');
            }
            Cache::set($key, 1, 120);
            Db::startTrans();
            $order = self::where('id', $order->id)->lock(true)->find();
            $order->role_id = $uid;
            $order->take_time = time();
            $order->status = self::STATUS_ORDER_RECEIVED;
            if (!$order->save()) {
                throw new Exception('操作失败');
            }
            Cache::rm($key);
            Db::commit();
            return true;
        } catch (Exception $e) {
            Db::rollback();
            Cache::rm($key);
            return self::setErrorInfo($e->getMessage());
        }
    }

    //确认完成订单
    public static function complete($uid, $order, $money, $admin_id = 0, $pay_type = self::PAY_TYPE_OFFLINE)
    {
        try {
            if ($admin_id == 0) {
                if ($order->role_id != $uid) {
                    throw new Exception('非法操作');
                }
            }
            if ($pay_type == self::PAY_TYPE_OFFLINE) {
                Db::startTrans();
                $category_name = RecycleOrderItemModel::categoryName($order->id);
                //增加用户的余额，财务记录
                UserModel::money($order->user_id, 0, $category_name);
                //如果存在上级，并且是用户的首单，增加上级的红包记录
                $saleUser = UserModel::where('id', $order->user_id)->find();
                if ($saleUser['pid']) {
                    $order_count = self::where('user_id', $order['user_id'])->where('status', self::STATUS_COMPLETED)->find();
                    if (!$order_count) {
                        $redbag = ConfigModel::getValue('invitation_user_money', 'basic');
                        $memo = "下级用户{$saleUser['nickname']}下单奖励";
                        UserModel::redbag($saleUser['pid'], $redbag, '邀好友', $memo);
                    }
                }
                //更新用户的订单状态
                $order->complete_time = time();
                $order->status = self::STATUS_COMPLETED;
                $order->actual_price = $money;
                $order->admin_id = $admin_id;//后台操作员id
                $order->pay_type = $pay_type;
                if (!$order->save()) {
                    throw new Exception('更新订单信息失败');
                }
                Db::commit();
                return true;
            } else {
                $wx = new Wxpay();
                $order['actual_price'] = $money;
                return $wx->getRecyclePayUrl($order);
            }
        } catch (Exception $e) {
            Db::rollback();
            return self::setErrorInfo($e->getMessage());
        }
    }

    //订单列表
    public static function lst($user_id, $params)
    {
        $page = !empty($params['page']) ? $params['page'] : 1;
        $limit = !empty($params['limit']) ? $params['limit'] : 10;
        $user = UserModel::info($user_id);
        $list = self::order('createtime desc');
        if ($user['role'] == UserModel::ROLE_RECYCLER) {
            //不同市的地区下的订单,不同区域的回收员不能查看，例如泉州回收员不能看厦门市的订单
            $rider = RiderModel::info($user_id);
            if (!$rider) {  //如果没有申请成为骑手的记录，就看不到订单
                return [];
            }
            $list = $list->where('province', $rider['province'])->where('city', $rider['city']);
            if (isset($params['status']) && $params['status']) {
                switch ($params['status']) {
                    case self::STATUS_PENDING_ORDER:
                        $list = $list->where('status', self::STATUS_PENDING_ORDER);
                        break;
                    case self::STATUS_ORDER_RECEIVED:
                    case self::STATUS_COMPLETED:
                        $list = $list->where('role_id', $user_id)->where('status', $params['status']);
                        break;
                    case self::STATUS_CANCEL:
                        $list = $list->where('status', $params['status'])
                            ->where(function ($query) use ($user_id) {
                                $query->where('role_id', $user_id)->whereOr('user_id', $user_id);
                            });
                        break;
                    default:
                        break;
                }
            }
        } else {
            $list = $list->where('user_id', $user_id);
            if (isset($params['status']) && $params['status']) {
                $list = $list->where('status', $params['status']);
            }
        }

        $list = $list->with('item');
        $list = $list->page((int)$page, (int)$limit);
        $list = $list->select();
        $data = [];
        $status = self::status();
        foreach ($list as $key => $value) {
            $category_name = [];
            foreach ($value['item'] as $k => $v) {
                $category_name[] = $v['category_name'];
            }
            $category_name = implode(',', $category_name);
            $data[$key]['id'] = $value['id'];
            $data[$key]['no'] = $value['no'];
            $data[$key]['images'] = $value['images'];
            $data[$key]['remark'] = $value['remark'];
            $data[$key]['category_name'] = $category_name;
            $data[$key]['reserve_time'] = date('Y-m-d H:i:s', $value['reserve_time']);
            $data[$key]['province'] = $value['province'];
            $data[$key]['city'] = $value['city'];
            $data[$key]['district'] = $value['district'];
            $data[$key]['address'] = $value['address'];
            $data[$key]['real_name'] = $value['real_name'];
            $data[$key]['mobile'] = $value['mobile'];
            $data[$key]['estimate_weight'] = $value['estimate_weight'];
            $data[$key]['estimate_price'] = $value['estimate_price'];
            $data[$key]['actual_price'] = $value['actual_price'];
            $data[$key]['status'] = $value['status'];
            $data[$key]['status_name'] = isset($status[$value['status']]) ? $status[$value['status']] : '';
            $data[$key]['is_self'] = $value['user_id'] == $user_id ? 1 : 0;
        }
        return $data;
    }

    //扫码获取用户的待处理回收的订单
    public static function scanList($role_id, $user_id)
    {
        $list = self::where('status', self::STATUS_ORDER_RECEIVED)->order('id desc');
        $list = $list->where('role_id', $role_id)->where('user_id', $user_id);
        $list = $list->select();
        $data = [];
        $status = self::status();
        foreach ($list as $key => $value) {
            $category_name = [];
            foreach ($value['item'] as $k => $v) {
                $category_name[] = $v['category_name'];
            }
            $category_name = implode(',', $category_name);
            $data[$key]['id'] = $value['id'];
            $data[$key]['no'] = $value['no'];
            $data[$key]['images'] = $value['images'];
            $data[$key]['remark'] = $value['remark'];
            $data[$key]['category_name'] = $category_name;
            $data[$key]['reserve_time'] = date('Y-m-d H:i:s', $value['reserve_time']);
            $data[$key]['province'] = $value['province'];
            $data[$key]['city'] = $value['city'];
            $data[$key]['district'] = $value['district'];
            $data[$key]['address'] = $value['address'];
            $data[$key]['real_name'] = $value['real_name'];
            $data[$key]['mobile'] = $value['mobile'];
            $data[$key]['estimate_weight'] = $value['estimate_weight'];
            $data[$key]['estimate_price'] = $value['estimate_price'];
            $data[$key]['actual_price'] = $value['actual_price'];
            $data[$key]['status'] = $value['status'];
            $data[$key]['status_name'] = isset($status[$value['status']]) ? $status[$value['status']] : '';
        }
        return $data;
    }

    //取消回收订单
    public static function cancel($cancel_id, $order)
    {
        $order->status = self::STATUS_CANCEL;
        $order->cancel_id = $cancel_id;
        $order->cancel_time = time();
        return $order->save();
    }
}